<?php

declare (strict_types = 1);

namespace App\Dao;

use App\Model\AuthEmployee;
use App\Model\AuthOrganization;

class AuthOrganizationDao
{
    use DaoTrait;
    public function __construct()
    {
        $this->driver = __CLASS__;
    }

    public function changeDriver(\Hyperf\Database\Model\Model $model)
    {
        $this->driver = $model;
        return $this;
    }

    public function resetDriver()
    {
        $this->driver = __CLASS__;
        return $this;
    }

    /**
     * 获取递归下级部门信息
     * @param $ids
     * @param string[] $columns //必须包含 id
     * @return array
     */
    public function searchRecursionOrganization($ids, $columns = ['*'])
    {
        $list = AuthOrganization::query()->whereIn('pid', $ids)->orderBy('sort')->get($columns)->toArray();
        $ids = array_column($list, 'id');
        if (!empty($ids)) {
            $list = array_merge($list, $this->searchRecursionOrganization($ids, $columns));
        }

        return $list;
    }

    /**
     * 根据公司id查询公司树信息
     *
     * @Author czm
     * @DateTime 2020-10-10
     * @param integer $company_id
     * @param integer $pid
     * @param boolean $hasEmployee 是否携带员工信息
     * @param integer $limit
     * @return void
     */
    public function getTreeWithPrincipal(int $company_id, int $pid = 0, bool $hasEmployee = false, int $limit = AuthOrganization::ORGANIZATION_RANK_LIMIT)
    {
        if ($limit < 0) {
            return [];
        }
        $limit--;
        $organzations = AuthOrganization::select('id', 'name', 'pid', 'grade', 'employee_id');
        // if ($hasEmployee) {
        //     $organzations = $organzations
        //         ->with(['hasPrincipalProject' => function ($query) {
        //             $query->select('auth_project.id', 'auth_project.name')->where('auth_project.is_del', 1)->where('auth_project.status', AuthEmployee::STATUS_NORMAL);
        //         }]);
        // }
        $organzations = $organzations->with(['hasEmployeeOne' => function ($query) {
            $query->select('auth_employee.id', 'auth_employee.name');
        }])
            ->where('company_id', $company_id)->where('pid', $pid)->orderBy('sort')->get()->each(function ($item) use ($hasEmployee) {
            if ($hasEmployee) {
                //追加负责部门
                $employee = AuthEmployee::select('id', 'name', 'duty_id')
                    ->with([
                        'hasDuty' => function ($query) {
                            $query->select('auth_duty.id', 'auth_duty.name');
                        },
                        // 'belongsToProject' => function ($query) {
                        //     $query->select('auth_project.id', 'auth_project.name')
                        //         ->where('auth_project_employee.type', AuthProjectEmployee::JOIN_TYPE)
                        //         ->where('auth_project_employee.organization_id', 0)
                        //         ->where('auth_project_employee.is_del', 1)
                        //         ->where('auth_project.status', AuthEmployee::STATUS_NORMAL)
                        //         ->where('auth_project.is_del', 1)
                        //     ;
                        // },
                    ])
                    ->where('organization_id', $item->id)
                    ->where('entry_status', AuthEmployee::ENTRY_STATUS_ING)
                    ->get()->each(function ($it) {
                    // $project_name = "";
                    $duty_name = "";

                    if ($it->hasDuty) {
                        $duty_name = $it->hasDuty->name;
                    }
                    // if ($it->belongsToProject) {
                    //     $project_name = implode("、", $it->belongsToProject->pluck('name')->toArray());
                    // }

                    // if ($it->partake_project == AuthEmployee::PARTAKE_PROJECT_ALL) {
                    //     $project_name = "全部";
                    // }
                    $it->forceFill([
                        // 'project_name' => $project_name,
                        'duty_name' => $duty_name,
                    ])->makeHidden(['hasDuty']);
                })->toArray();

                // if ($item->hasPrincipalProject) {
                //     $principal_project_name = implode("、", $item->hasPrincipalProject->pluck('name')->toArray());
                // }

                $item->forceFill([
                    'employee' => $employee,
                    // 'principal_project_name' => $principal_project_name,
                ]);
            }
        })->toArray();
        foreach ($organzations as $key => $val) {
            $organzations[$key]['_child'] = $this->getTreeWithPrincipal($company_id, $val['id'], $hasEmployee, $limit);
        }
        return $organzations;
    }

    public function getTreeWithEmployee(int $company_id, int $pid = 0, int $limit = AuthOrganization::ORGANIZATION_RANK_LIMIT)
    {
        if ($limit < 0) {
            return [];
        }
        $limit--;
        $organzations = AuthOrganization::select('id', 'name', 'pid', 'grade', 'employee_id')
            ->where('company_id', $company_id)->where('pid', $pid)->orderBy('sort')->get()->each(function ($item) {
            //追加负责部门
            $employee = AuthEmployee::select('id', 'name', 'duty_id')
                ->with([
                    'hasDuty' => function ($query) {
                        $query->select('auth_duty.id', 'auth_duty.name');
                    },
                ])
                ->where('organization_id', $item->id)
                ->where('entry_status', AuthEmployee::ENTRY_STATUS_ING)
                ->get()->each(function ($it) {
                $duty_name = "";

                if ($it->hasDuty) {
                    $duty_name = $it->hasDuty->name;
                }
                $it->forceFill([
                    'duty_name' => $duty_name,
                ])->makeHidden(['hasDuty']);
            })->toArray();
            $item->forceFill([
                'employee' => $employee,
            ]);
        })->toArray();

        foreach ($organzations as $key => $val) {
            $organzations[$key]['_child'] = $this->getTreeWithEmployee($company_id, $val['id'], $limit);
        }
        return $organzations;
    }

    /**
     * 寻找指定部门下面的分支id
     *
     * @Author czm
     * @DateTime 2020-09-10
     * @param [type] $organization_id
     * @param [type] $level
     * @return array
     */
    public function findBranchIds($organization_id, $level = AuthOrganization::ORGANIZATION_RANK_LIMIT): array
    {
        if ($level < 0) {
            return [];
        }
        $level--;
        $organizations = AuthOrganization::select('id', 'pid')->where('pid', $organization_id)->orderBy('sort')->get()->toArray();
        $ids = [];
        foreach ($organizations as $val) {
            $ids[] = $val['id'];
            $ids = array_merge($ids, $this->findBranchIds($val['id'], $level));
        }
        return array_unique($ids);
    }

    /**
     * 寻找指定部门下面的上级id
     *
     * @Author czm
     * @DateTime 2020-09-10
     * @param [type] $organization_id
     * @param [type] $level
     * @return array
     */
    public function findParentIds($organization_id, $level = AuthOrganization::ORGANIZATION_RANK_LIMIT): array
    {
        if ($level < 0 || !$organization_id) {
            return [];
        }
        $level--;
        $organization = AuthOrganization::find($organization_id);
        $ids = [];
        if ($organization) {
            $ids[] = $organization->id;
            $ids = array_merge($ids, $this->findParentIds($organization->pid, $level));
        }
        return array_unique($ids);
    }

    /**
     * 寻找指定部门下面的上级id与负责人信息
     *
     * @Author czm
     * @DateTime 2020-09-10
     * @param [type] $organization_id
     * @param [type] $level
     * @return array
     */
    public function findParentIdsWithPrincipal($organization_id, $level = AuthOrganization::ORGANIZATION_RANK_LIMIT): array
    {
        if ($level < 0 || !$organization_id) {
            return [];
        }
        $level--;
        $organization = AuthOrganization::find($organization_id);
        $ids = [];
        if ($organization) {
            $ids[$organization->id] = $organization->employee_id;
            $organization->pid && $ids += $this->findParentIdsWithPrincipal($organization->pid, $level);
        }
        return $ids;
    }

    /**
     * 根据id数组获取全部
     * @param $ids
     * @param string[] $columns
     */
    public function getArrayWhereInId($ids, $columns = ['*'])
    {
        return AuthOrganization::query()->whereIn('id', $ids)->orderBy('sort')->get($columns)->toArray();
    }

    /**
     * 查找当前部门id下的授权部门
     *
     * @Author czm
     * @DateTime 2020-09-29
     * @param integer $organization_id
     * @return void
     */
    public function findTopCover(int $organization_id)
    {
        if (!$organization_id) {
            return false;
        }
        $info = AuthOrganization::find($organization_id);
        $organization = AuthOrganization::find($info->pid);
        if ($organization && $organization->cover_next == AuthOrganization::COVER_YES) {
            return $organization->id;
        } else if (!$organization) {
            return false;
        } else if (!$organization->pid) {
            return false;
        } else {
            return $this->findTopCover($organization->pid);
        }
    }

    public function searchByWhereIn($where, $key, $whereIn, $columns = ['*'])
    {
        return AuthOrganization::query()->where($where)->whereIn($key, $whereIn)->get($columns)->toArray();

    }
}
